package com.aispeech.aitv.voice;

import android.text.TextUtils;
import android.util.Log;
import com.aispeech.AIError;
import com.aispeech.AIResult;
import com.aispeech.aitv.MyApplication;
import com.aispeech.common.AIConstant;
import com.aispeech.common.JSONResultParser;
import com.aispeech.common.Util;
import com.aispeech.export.engines.AICloudASREngine;
import com.aispeech.export.engines.AILocalTTSEngine;
import com.aispeech.export.engines.AILocalWakeupDnnEngine;
import com.aispeech.export.listeners.AIASRListener;
import com.aispeech.export.listeners.AIAuthListener;
import com.aispeech.export.listeners.AILocalWakeupDnnListener;
import com.aispeech.export.listeners.AITTSListener;
import com.aispeech.speech.AIAuthEngine;
import java.io.FileNotFoundException;

/**
 * 语音引擎控制类
 *
 * @author rain  01.17 2018
 */

public class VoiceEngineManage {

    private static final String TAG = "VoiceEngineManage";
    private static VoiceEngineManage mInstance;

    private AIAuthEngine mAuthEngine;
    private AILocalWakeupDnnEngine mWakeupEngine;
    private AICloudASREngine mAsrEngine;
    private AILocalTTSEngine mTTSEngine;

    private MyEngineListener myEngineListener;

    private final String APP_KEY = "1494821461859668";
    private final String SECRET_KEY = "c3e8e482e71b4a803c9b65ea56f7e27f";

    private String[] WAKEUP_WORDS = {"ni zhen bang", "ji lu xin qing", "fen xiang hao you", "fa peng you quan"};
    private float[] WAKEUP_THREADS = {0.120f, 0.1f, 0.1f, 0.1f};

    private VoiceEngineManage() {
    }

    public static VoiceEngineManage getInstance() {
        Log.d(TAG, "getInstance: ");
        if (null == mInstance) {
            mInstance = new VoiceEngineManage();
        }
        return mInstance;
    }

    public void initAllEngine(MyEngineListener listener) {
        Log.d(TAG, "initAllEngine: ");

        myEngineListener = listener;
        mAuthEngine = AIAuthEngine.getInstance(MyApplication.getContext());
        try {
            mAuthEngine.init(APP_KEY, SECRET_KEY, "");
            mAuthEngine.setOnAuthListener(new AIAuthListener() {
                @Override
                public void onAuthSuccess() {
                    Log.d(TAG, "onAuthSuccess: ");
//                    sendBroadcast(new Intent("dui.intent.action.init_complete"));
//                    initEngine();
                    initTTSEngine();
                    myEngineListener.onInitResult("auth");
                }

                @Override
                public void onAuthFailed(final String result) {
                    Log.d(TAG, "onAuthFailed: result = " + result);
                    try {
                        Thread.sleep(800);
                        mAuthEngine.doAuth();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });

            if (mAuthEngine.isAuthed()) {
                initTTSEngine();
                myEngineListener.onInitResult("auth");
            } else {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mAuthEngine.doAuth();
                    }
                }).start();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void initWakeupEngine() {
        Log.d(TAG, "initWakeupEngine: ");
        if (null != mWakeupEngine) {
            mWakeupEngine.destroy();
        }
        mWakeupEngine = AILocalWakeupDnnEngine.createInstance(); //创建实例
        mWakeupEngine.setResBin(SampleConstants.wakeup_res); //非自定义唤醒资源可以不用设置words和thresh，资源已经自带唤醒词
        mWakeupEngine.setWords(WAKEUP_WORDS);
        mWakeupEngine.setThreshold(WAKEUP_THREADS);

        mWakeupEngine.init(MyApplication.getContext(), new AIWakeupListenerImpl(), APP_KEY, SECRET_KEY);
        mWakeupEngine.setStopOnWakeupSuccess(true);//设置当检测到唤醒词后自动停止唤醒引擎
        mWakeupEngine.setDeviceId(Util.getIMEI(MyApplication.getContext()));

    }

    private void initTTSEngine() {
        Log.d(TAG, "initTTSEngine: ");
        if (mTTSEngine != null) {
            mTTSEngine.destroy();
        }

        mTTSEngine = AILocalTTSEngine.createInstance();//创建实例
        mTTSEngine.setResource(SampleConstants.tts_res);
        mTTSEngine.setDictDbName(SampleConstants.tts_db);
        mTTSEngine.setRealBack(true);//设置本地合成使用实时反馈
        mTTSEngine.init(MyApplication.getContext(), new AILocalTTSListenerImpl(), APP_KEY, SECRET_KEY);//初始化合成引擎
        mTTSEngine.setSpeechRate(0.85f);//设置语速
        mTTSEngine.setDeviceId(Util.getIMEI(MyApplication.getContext()));

    }

    private void initAsrEngine() {
        if (null != mAsrEngine) {
            mAsrEngine.destroy();
        }
        mAsrEngine = AICloudASREngine.createInstance();

        mAsrEngine.setVadResource(SampleConstants.vad_res);
        mAsrEngine.setDeviceId(Util.getIMEI(MyApplication.getContext()));
        mAsrEngine.setHttpTransferTimeout(10);
        mAsrEngine.init(MyApplication.getContext(), new AICloudASRListenerImpl(), APP_KEY, SECRET_KEY);
        mAsrEngine.setNoSpeechTimeOut(0);
    }

    public void destroyEngine() {
        Log.d(TAG, "destroyEngine: ");
        if (null != mAsrEngine) {
            mAsrEngine.destroy();
        }
        if (null != mWakeupEngine) {
            mWakeupEngine.destroy();
        }
        if (null != mTTSEngine) {
            mTTSEngine.destroy();
        }
    }


    /**
     * 播报文本内容
     *
     * @param text 需要播报的内容
     */
    public void playTTS(String text) {
        Log.d(TAG, "playTTS with: text = " + text + "");
        try {
            mTTSEngine.speak(text, "1024");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void startWakeup() {
        Log.d(TAG, "startWakeup: ");
        if (null != mWakeupEngine) {
            mWakeupEngine.start();
        }
    }

    public void stopWakeup() {
        Log.d(TAG, "stopWakeup: ");
        if (null != mWakeupEngine) {
            mWakeupEngine.stop();
        }
    }

    public void startAsr() {
        Log.d(TAG, "startAsr: ");
        if (null != mAsrEngine) {
            mAsrEngine.start();
        }
    }

    public void stopAsr() {
        Log.d(TAG, "stopAsr: cancel");
        if (null != mAsrEngine) {
            mAsrEngine.cancel();
        }
    }


    private class AILocalTTSListenerImpl implements AITTSListener {

        @Override
        public void onInit(int status) {
            Log.i(TAG, "初始化完成，返回值：" + status);
            Log.i(TAG, "onInit");
            if (status == AIConstant.OPT_SUCCESS) {
                Log.d(TAG, "初始化成功!");
                initWakeupEngine();
                myEngineListener.onInitResult("tts");
            } else {
                Log.d(TAG, "初始化失败!" + status);
            }
        }

        @Override
        public void onProgress(int currentTime, int totalTime, boolean isRefTextTTSFinished) {
            Log.d(TAG, "当前:" + currentTime + "ms, 总计:" + totalTime + "ms, 可信度:" + isRefTextTTSFinished);
        }

        @Override
        public void onError(String utteranceId, AIError error) {

            Log.d(TAG, "onError with: utteranceId = " + utteranceId + ", error = " + error.toString() + "");
        }

        @Override
        public void onReady(String utteranceId) {
            Log.d(TAG, "onReady: tts");
        }

        @Override
        public void onCompletion(String utteranceId) {
            Log.d(TAG, "onCompletion: tts");
        }
    }

    private class AIWakeupListenerImpl implements AILocalWakeupDnnListener {

        private String mWakeupWord = "";

        @Override
        public void onError(AIError error) {
            Log.d(TAG, "onError with: error = " + error.toString() + "");
        }

        @Override
        public void onInit(int status) {
            Log.i(TAG, "Init result " + status);
            if (status == AIConstant.OPT_SUCCESS) {
                initAsrEngine();
//                mWakeupEngine.start();
//                mEngine.setNetWorkState("WIFI"); //上传音频
                myEngineListener.onInitResult("wakeup");
            } else {
                Log.d(TAG, "onInit: wakeup init err");
            }
        }

        @Override
        public void onRmsChanged(float rmsdB) {
        }

        @Override
        public void onWakeup(String recordId, double confidence, String wakeupWord) {
            Log.e(TAG, "wakeup foreground " + wakeupWord);
//            onCall(wakeupWord, "");
            //在这里启动其他引擎，比如tts或者识别
            mWakeupWord = wakeupWord;
        }

        @Override
        public void onReadyForSpeech() {

        }

        @Override
        public void onBufferReceived(byte[] buffer) {
        }

        @Override
        public void onRecorderReleased() {
        }

        @Override
        public void onWakeupEngineStopped() {
//            mWakeupEngine.start();
            Log.d(TAG, "onWakeupEngineStopped: ");
            if (TextUtils.isEmpty(mWakeupWord)) {
                return;
            }
            myEngineListener.onWakeupResult(mWakeupWord);
            mWakeupWord = "";
        }

    }

    private class AICloudASRListenerImpl implements AIASRListener {

        @Override
        public void onReadyForSpeech() {
            Log.d(TAG, "onReadyForSpeech: ");
        }

        @Override
        public void onBeginningOfSpeech() {
            Log.d(TAG, "onBeginningOfSpeech: ");
        }

        @Override
        public void onEndOfSpeech() {
            Log.d(TAG, "onEndOfSpeech: ");
        }

        @Override
        public void onRmsChanged(float rmsdB) {

        }

        @Override
        public void onError(AIError error) {
            Log.e(TAG, "error:" + error.toString());
            myEngineListener.onAsrResult(error.toString(), true);
        }

        @Override
        public void onResults(AIResult results) {
            if (results.isLast()) {
                if (results.getResultType() == AIConstant.AIENGINE_MESSAGE_TYPE_JSON) {
                    Log.i(TAG, "result JSON = " + results.getResultObject().toString());
                    // 可以使用JSONResultParser来解析识别结果
                    // 结果按概率由大到小排序
                    JSONResultParser parser = new JSONResultParser(results.getResultObject()
                        .toString());
//                    String recordId = parser.getRecordId();
                    Log.d(TAG, "onResults: rec = " + parser.getRec());
                    myEngineListener.onAsrResult(parser.getRec(), true);
                }
            }
        }

        @Override
        public void onInit(int status) {
            Log.i(TAG, "Init result " + status);
            if (status == AIConstant.OPT_SUCCESS) {
                Log.d(TAG, "onInit: 初始化识别引擎成功");
                myEngineListener.onInitResult("asr");
                myEngineListener.onInitResult("success");
            } else {
                Log.d(TAG, "onInit: 初始化识别引擎失败");
            }
        }

        @Override
        public void onRecorderReleased() {
            Log.d(TAG, "onRecorderReleased: ");
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onNotOneShot() {
            // TODO Auto-generated method stub

        }

    }

}
